/*
 * Copyright (c) 2012, Xiao yuan, Zhiyi wu. All rights reserved.
 *
 */

package org.zhiyiw.jason;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.ImageIcon;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeSelectionModel;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.awt.*;

//@SuppressWarnings("serial")
public class UIFrame extends JPanel implements ActionListener {
	static private final String newline = "\n";
	JButton openButton1, openButton2, compareButton;
	JTextArea log;
	JFileChooser fc;

	JTextArea OrigTree;
	JTextArea TargTree;

	JTextArea errMsg;
	JTextArea corMsg;

	private JTree tree1;
	private JTree tree2;

	dataBuild db;
	dataBuild db2;

	TreeDisplay OrininalTree;
	TreeDisplay TargetTree;

	boolean isValidFile = false;
	BufferedImage myImage = null;

	public void toGREEN(JTextArea n) {
		n.setForeground(Color.GREEN);
	}

	public void toRED(JTextArea n) {
		n.setForeground(Color.RED);
	}

	public UIFrame() {
		super(new GridBagLayout());

		// Create the log first, because the action listeners
		// need to refer to it.
		log = new JTextArea(5, 20);
		log.setMargin(new Insets(5, 5, 5, 5));
		log.setEditable(false);

		Font font1 = new Font("Verdana", Font.PLAIN, 12);
		log.setFont(font1);
		log.setForeground(Color.BLUE);

		JScrollPane logScrollPane = new JScrollPane(log);

		// Create a file chooser
		fc = new JFileChooser();

		Font font2 = new Font("Verdana", Font.PLAIN, 12);
		errMsg = new JTextArea(5, 10);
		errMsg.setFont(font2);
		errMsg.setForeground(Color.RED);
		JScrollPane errScrollPane = new JScrollPane(errMsg);

		try {
			myImage = ImageIO.read(new File("android.jpeg"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		openButton1 = new JButton("Open original zip File...",
				createImageIcon("Open16.gif"));
		openButton1.setPreferredSize(new Dimension(200, 40));
		openButton1.addActionListener(this);

		// Create the save button. We use the image from the JLF
		// Graphics Repository (but we extracted it from the jar).
		openButton2 = new JButton("Open target zip File...",
				createImageIcon("Open16.gif"));
		openButton2.setPreferredSize(new Dimension(200, 40));
		openButton2.addActionListener(this);

		compareButton = new JButton("Compare both File",
				createImageIcon("Save16.gif"));
		compareButton.setPreferredSize(new Dimension(200, 40));
		compareButton.addActionListener(this);

		// For layout purposes, put the buttons in a separate panel
		JPanel buttonPanel = new JPanel(); // use FlowLayout
		buttonPanel.setPreferredSize(new Dimension(800, 100));
		// buttonPanel.setContentPane(new ImagePanel(myImage));
		buttonPanel.add(openButton1);
		buttonPanel.add(openButton2);
		buttonPanel.add(compareButton);

		// define tree 1 root node
		DefaultMutableTreeNode top1 = new DefaultMutableTreeNode(
				"Original File");
		// createNodes(top);

		tree1 = new JTree(top1);
		tree1.getSelectionModel().setSelectionMode(
				TreeSelectionModel.SINGLE_TREE_SELECTION);
		tree1.setRowHeight(25);

		// define tree 2 root node
		DefaultMutableTreeNode top2 = new DefaultMutableTreeNode("Target File");
		// createNodes(top);

		tree2 = new JTree(top2);
		tree2.getSelectionModel().setSelectionMode(
				TreeSelectionModel.SINGLE_TREE_SELECTION);
		tree2.setRowHeight(25);
		JScrollPane treeView1 = new JScrollPane(tree1);
		JScrollPane treeView2 = new JScrollPane(tree2);

		JSplitPane treePanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
		// treePanel.setLayout(getLayout());
		treePanel.setLeftComponent(treeView1);
		treePanel.setRightComponent(treeView2);

		treePanel.setDividerLocation(400);
		treePanel.setPreferredSize(new Dimension(800, 400));

		GridBagConstraints c = new GridBagConstraints();

		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0.5;
		c.gridx = 0;
		c.gridy = 0;
		add(openButton1, c);

		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0.5;
		c.gridx = 1;
		c.gridy = 0;
		add(openButton2, c);

		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0.5;
		c.gridx = 2;
		c.gridy = 0;
		add(compareButton, c);

		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0.0;
		c.gridwidth = 3;
		// c.ipady = 300;
		c.gridx = 0;
		c.gridy = 1;
		add(treePanel, c);

		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0.0;
		c.ipady = 50;
		c.gridx = 0;
		c.gridy = 2;
		add(errScrollPane, c);

		c.fill = GridBagConstraints.HORIZONTAL;
		c.ipady = 50;
		c.gridx = 0;
		c.gridy = 3;
		add(logScrollPane, c);

	}

	public String zipFilestream(ZipFile zf) {
		ZipEntry entry;
		Enumeration<? extends ZipEntry> enu = zf.entries();
		InputStream is = null;
		String str = null;
		while (enu.hasMoreElements()) {
			entry = (ZipEntry) enu.nextElement();

			if (entry.isDirectory())
				continue;

			System.out.println(entry.getName());
			String filename = entry.getName();
			String last3char = filename.substring(filename.length() - 12,
					filename.length());
			System.out.println(last3char);

			if (last3char.equals("/Screen1.scm")) {
				// isValidFile = true;
				try {
					is = zf.getInputStream(entry);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			int len = 0;
			byte[] b = new byte[20480];
			try {
				while ((len = is.read(b)) != -1) {
					str = new String(b, 0, len, "gb2312");
				}

			} catch (Exception e) {
				System.out.println("byte read Error");
			}

		}
		return str;

	}

	public void actionPerformed(ActionEvent e) {

		ZipFile zf = null;

		// choose original file button
		if (e.getSource() == openButton1) {
			int returnVal = fc.showOpenDialog(UIFrame.this);

			if (returnVal == JFileChooser.APPROVE_OPTION) {
				File file = fc.getSelectedFile();
				// This is where a real application would open the file.
				log.append("Opening original file: " + file.getName() + "."
						+ newline);

				try {
					zf = new ZipFile(file);
				} catch (IOException e1) {
					// TODO Auto-generated catch block

					e1.printStackTrace();
				}

				db = new dataBuild(zipFilestream(zf));

				DefaultTreeModel treeModel1 = (DefaultTreeModel) tree1
						.getModel();
				DefaultMutableTreeNode root = (DefaultMutableTreeNode) (treeModel1
						.getRoot());
				
				root.removeAllChildren();

				OrininalTree = new TreeDisplay();
				DefaultMutableTreeNode root1 = OrininalTree.treeNodes(root,
						db.compArr.get(db.compArr.size() - 1));

				treeModel1.setRoot(root1);
				tree1.setCellRenderer(new myRenderer());

				treeModel1.reload();

				System.out.println("XXXXXXXXXXXXX"
						+ OrininalTree.TreeDisp(db.compArr.get(db.compArr
								.size() - 1)));

				// test text result output
				log.append("The original file has oppened !!" + newline);

			} else {
				log.append("Open command cancelled by user." + newline);
			}
			log.setCaretPosition(log.getDocument().getLength());

			// choose target file button
		} else if (e.getSource() == openButton2) {
			int returnVal = fc.showOpenDialog(UIFrame.this);
			if (returnVal == JFileChooser.APPROVE_OPTION) {
				File file = fc.getSelectedFile();
				// This is where a real application would save the file.
				log.append("\nOpening target file: " + file.getName() + "."
						+ newline);

				// if(isValidFile) {

				try {
					zf = new ZipFile(file);
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}

				db2 = new dataBuild(zipFilestream(zf));

				DefaultTreeModel treeModel2 = (DefaultTreeModel) tree2
						.getModel();

				DefaultMutableTreeNode root = (DefaultMutableTreeNode) (treeModel2
						.getRoot());
				
				root.removeAllChildren();

				TargetTree = new TreeDisplay();
				DefaultMutableTreeNode root2 = TargetTree.treeNodes(root,
						db2.compArr.get(db2.compArr.size() - 1));

				treeModel2.setRoot(root2);
				tree2.setCellRenderer(new myRenderer());
				treeModel2.reload();

//				TargTree.append(TargetTree.TreeDisp(db2.compArr.get(db2.compArr
//						.size() - 1)));

				// test text result output
				log.append("The target file has oppened !!" + newline);

			} else {
				log.append("Open command cancelled by user." + newline);
			}
			log.setCaretPosition(log.getDocument().getLength());

			// choose compare both files button
		} else if (e.getSource() == compareButton) {

			if (db == null && db2 == null) {
				log.append("Pleases add Files !!!\n");
			}
			if (db == null && db2 != null) {
				log.append("Pleases add Original file !!!\n");
			}
			if (db != null && db2 == null) {
				log.append("Pleases add Target file !!!\n");
			}
			if (db != null && db2 != null) {
				compareUI testUI = new compareUI();
				if (testUI.compare(db.compArr, db2.compArr).equals(
						"GREAT!! Structure matched!!")) {
					toGREEN(errMsg);
					errMsg.setText("");
					errMsg.append(testUI.compare(db.compArr, db2.compArr)
							+ "\n");
					if(!testUI.compareProperty(db.compArr, db2.compArr).equals("Great!! Properties matched!!"))
						toRED(errMsg);
					errMsg.append(testUI.compareProperty(db.compArr, db2.compArr));
				} else {
					toRED(errMsg);
					errMsg.setText("");
					errMsg.append(testUI.compare(db.compArr, db2.compArr));
					errMsg.append("Evaluation Details -->"
							+ testUI.compareTypeNum(db, db2));
				}

				if (testUI.totalArrangeEqual(db, db2)) {
					errMsg.append(testUI.compareArrangement(db.compArr,
							db2.compArr));
				}

			}

		}

	}

	/** Returns an ImageIcon, or null if the path was invalid. */
	protected static ImageIcon createImageIcon(String path) {
		java.net.URL imgURL = UIFrame.class.getResource(path);
		if (imgURL != null) {
			return new ImageIcon(imgURL);
		} else {
			System.err.println("Couldn't find file: " + path);
			return null;
		}
	}

	/**
	 * Create the GUI and show it. For thread safety, this method should be
	 * invoked from the event-dispatching thread.
	 */
	public void createAndShowGUI() {

		// Create and set up the window.
		JFrame frame = new JFrame("AppInventor UI Grader Ver: 0.2");

		// frame.setTitle("Simple example");
		frame.setSize(800, 600);
		frame.setLocationRelativeTo(null);

		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		// Create and set up the content pane.
		UIFrame newContentPane = new UIFrame();
		// newContentPane.setSize(300, 200);
		newContentPane.setOpaque(true); // content panes must be opaque

		frame.setContentPane(newContentPane);

		// Display the window.
		frame.pack(); // it will automatically change the size of the frames
		// according to the size of components in it.
		frame.setVisible(true);
	}

}